package cn.car.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.hutool.core.date.DatePattern.PURE_DATETIME_MS_FORMAT;

@Slf4j
public class CarStringUtil {


    public static String decodeUnicode(String unicodeStr) {
        final Pattern pattern = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");
        final Matcher matcher = pattern.matcher(unicodeStr);
        final StringBuilder decodedString = new StringBuilder();
        while (matcher.find()) {
            int codePoint = Integer.parseInt(matcher.group(1), 16);
            matcher.appendReplacement(decodedString, Character.toString((char) codePoint));
        }
        matcher.appendTail(decodedString);
        return decodedString.toString();
    }

    /**
     * 生成文件名，格式为：yyyyMMddHHmmssSSS-编号.suffix
     * 每天编号从0开始递增
     *
     * @param suffix 文件后缀，如 ".txt"
     * @return 生成的文件名
     */
    public static String generateFileName(String suffix) {

        // 获取当前时间戳
        final String timestamp = DateUtil.format(new Date(), PURE_DATETIME_MS_FORMAT);
        // 生成文件名
        return timestamp + "-" + RandomUtil.randomString(8) + suffix;
    }

    public static String toNonBase64JsonString(Object obj) {
        try {
            if (Objects.isNull(obj)) {
                return null;
            }
            return regexReplace(
                    obj instanceof String ? ((String) obj) : JSON.toJSONString(obj),
                    "\"(/9j/[\\s\\S]*?)\"",
                    (str) -> "\"@base64_jpg_" + (str.length() - 2) + "_" + calcMD5(str.replaceAll("\"", "")) + "\""
            );
        } catch (Throwable ignore) {
            return "toNonBase64JsonString error.";
        }
    }

    public static String calcMD5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(str.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            return str.substring(0, Math.min(32, str.length()));
        }
    }

    /**
     * 对一个字符串进行替换，并且自定义替换方法。<br>
     * 注意：handler拿到的部分是regex全部匹配部分。<br>
     * 例如 regex = "aaa(.*?)bbb" ,str="ccc aaa xxxxx bbb ddd". 那么handler拿到的是 "aaa xxxxx bbb",而并不只是传统正则中捕获到的" xxxxx "
     *
     * @param str     被操作的字符串
     * @param regex   被替换部分的正则表达式
     * @param handler 被替换部分的替换器。
     * @return 处理后的字符串
     */
    public static String regexReplace(String str, String regex, ReplaceHandler handler) {
        return regexReplace(str, Pattern.compile(regex), handler);
    }


    /**
     * 对一个字符串进行替换，并且自定义替换方法。<br>
     * 注意：handler拿到的部分是regex全部匹配部分。<br>
     * 例如 regex = "aaa(.*?)bbb" ,str="ccc aaa xxxxx bbb ddd". 那么handler拿到的是 "aaa xxxxx bbb",而并不只是传统正则中捕获到的" xxxxx "
     *
     * @param str     被操作的字符串
     * @param pattern 被替换部分的正则对象
     * @param handler 被替换部分的替换器
     * @return 处理后的字符串
     */
    public static String regexReplace(String str, Pattern pattern, ReplaceHandler handler) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        Matcher matcher = pattern.matcher(str);

        boolean result = matcher.find();
        if (!result) {
            // normal char sequence
            return str;
        }

        int start = 0;
        StringBuilder sb = new StringBuilder();
        do {
            // append before
            sb.append(str, start, matcher.start());
            // append replacement
            sb.append(handler.onReplace(str.substring(matcher.start(), matcher.end())));
            start = matcher.end();
            result = matcher.find();
        } while (result);

        // append tail
        if (start < str.length()) {
            sb.append(str, start, str.length());
        }

        return sb.toString();
    }

    /**
     * 替换器
     */
    public interface ReplaceHandler {
        /**
         * 替换方法
         *
         * @param token 被替换的字符串
         * @return token替换后的结果
         */
        Object onReplace(String token);
    }


    /**
     * 用于获取文件名且不带扩展名
     */
    public static String getFileNameWithoutExtension(String filePath) {
        File file = new File(filePath);
        String name = file.getName();
        int lastIndexOf = name.lastIndexOf('.');
        return lastIndexOf == -1 ? name : name.substring(0, lastIndexOf);
    }
}
